#include "TestBed/TestBed.h"

#include "Framework/Prerequisites.h"

#include "Geometry/CustomObject.h"
#include "Graphics/IDeviceBufferManager.h"
#include "Graphics/IRenderEngine.h"
#include "Scene/SceneNode.h"




using namespace tyro;

Geometry::CustomObject* createCubeMesh(String name, String matName, Graphics::IDeviceBufferManager* bufferMgr, Graphics::MaterialManager* materialMgr) {

	Geometry::CustomObject* cube = new Geometry::CustomObject(name, bufferMgr);
	cube->BeginBuild(matName, materialMgr);

	cube->AddVertex(0.5,-0.5,1.0);cube->AddNormal(0.408248,-0.816497,0.408248);cube->AddTextureCoord(1,0);
	cube->AddVertex(-0.5,-0.5,0.0);cube->AddNormal(-0.408248,-0.816497,-0.408248);cube->AddTextureCoord(0,1);
	cube->AddVertex(0.5,-0.5,0.0);cube->AddNormal(0.666667,-0.333333,-0.666667);cube->AddTextureCoord(1,1);
	cube->AddVertex(-0.5,-0.5,1.0);cube->AddNormal(-0.666667,-0.333333,0.666667);cube->AddTextureCoord(0,0);
	cube->AddVertex(0.5,0.5,1.0);cube->AddNormal(0.666667,0.333333,0.666667);cube->AddTextureCoord(1,0);
	cube->AddVertex(-0.5,-0.5,1.0);cube->AddNormal(-0.666667,-0.333333,0.666667);cube->AddTextureCoord(0,1);
	cube->AddVertex(0.5,-0.5,1.0);cube->AddNormal(0.408248,-0.816497,0.408248);cube->AddTextureCoord(1,1);
	cube->AddVertex(-0.5,0.5,1.0);cube->AddNormal(-0.408248,0.816497,0.408248);cube->AddTextureCoord(0,0);
	cube->AddVertex(-0.5,0.5,0.0);cube->AddNormal(-0.666667,0.333333,-0.666667);cube->AddTextureCoord(0,1);
	cube->AddVertex(-0.5,-0.5,0.0);cube->AddNormal(-0.408248,-0.816497,-0.408248);cube->AddTextureCoord(1,1);
	cube->AddVertex(-0.5,-0.5,1.0);cube->AddNormal(-0.666667,-0.333333,0.666667);cube->AddTextureCoord(1,0);
	cube->AddVertex(0.5,-0.5,0.0);cube->AddNormal(0.666667,-0.333333,-0.666667);cube->AddTextureCoord(0,1);
	cube->AddVertex(0.5,0.5,0.0);cube->AddNormal(0.408248,0.816497,-0.408248);cube->AddTextureCoord(1,1);
	cube->AddVertex(0.5,-0.5,1.0);cube->AddNormal(0.408248,-0.816497,0.408248);cube->AddTextureCoord(0,0);
	cube->AddVertex(0.5,-0.5,0.0);cube->AddNormal(0.666667,-0.333333,-0.666667);cube->AddTextureCoord(1,0);
	cube->AddVertex(-0.5,-0.5,0.0);cube->AddNormal(-0.408248,-0.816497,-0.408248);cube->AddTextureCoord(0,0);
	cube->AddVertex(-0.5,0.5,1.0);cube->AddNormal(-0.408248,0.816497,0.408248);cube->AddTextureCoord(1,0);
	cube->AddVertex(0.5,0.5,0.0);cube->AddNormal(0.408248,0.816497,-0.408248);cube->AddTextureCoord(0,1);
	cube->AddVertex(-0.5,0.5,0.0);cube->AddNormal(-0.666667,0.333333,-0.666667);cube->AddTextureCoord(1,1);
	cube->AddVertex(0.5,0.5,1.0);cube->AddNormal(0.666667,0.333333,0.666667);cube->AddTextureCoord(0,0);

	cube->AddTriangle(0,1,2);      cube->AddTriangle(3,1,0);
	cube->AddTriangle(4,5,6);      cube->AddTriangle(4,7,5);
	cube->AddTriangle(8,9,10);      cube->AddTriangle(10,7,8);
	cube->AddTriangle(4,11,12);   cube->AddTriangle(4,13,11);
	cube->AddTriangle(14,8,12);   cube->AddTriangle(14,15,8);
	cube->AddTriangle(16,17,18);   
	cube->AddTriangle(16,19,17);

	cube->EndBuild(); 

	return cube;

}



TestBed::TestBed(Engine::Engine& engine)
: Engine::Program(engine)
,	activeCamera(0)
,	activeSceneManager(0)
,	activeWindow(0)
{
}

bool TestBed::Initialise()
{
	activeWindow = engine.Initialise();
	activeSceneManager = engine.CreateSceneManager();
	activeRenderEngine = engine.GetRenderEngine();
	activeMaterialManager = engine.GetMaterialManager();
	CreateCamera();
	CreateViewport();
	CreateScene();

	return true;
}

void TestBed::Release()
{
}

void TestBed::Quit()
{
}


void TestBed::Update()
{


	
}

void TestBed::Render()
{
	//activeCamera->Rotate(Math::Vector3f(0,0,1), Math::DegreesToRadian(1.05f));
	Math::Vector3f vec = activeCamera->GetTranslation();

	if (vec.z < -0)
	{
		vec.z = 100;
		activeCamera->SetTranslation(vec);
	}
	vec.z -= 0.009f;

	activeCamera->SetTranslation(vec);
}

void TestBed::CreateCamera()
{
	activeCamera = activeSceneManager->CreateCamera();
	activeCamera->SetTranslation(Math::Vector3f(0, 0, 100));
	activeCamera->SetNearClipDistance(1.0f);
}

void TestBed::CreateViewport()
{
	Graphics::IViewport* viewport = activeWindow->AddViewport(activeCamera);
	viewport->SetBackColour(Graphics::Colour::Black);
	activeCamera->SetAspectRatio(FLOAT_32(viewport->GetActWidth()) / FLOAT_32(viewport->GetActHeight()));
}

void TestBed::CreateScene()
{

	int num = 200;
	for(int i=0; i < num; i++)
	{
		FLOAT_32 x = Math::RandomNumber<FLOAT_32>(0, (num / 16));
		x -= (num / 32);
		FLOAT_32 y = Math::RandomNumber<FLOAT_32>(0, (num / 16));
		y -= (num / 32);
		FLOAT_32 z = Math::RandomNumber<FLOAT_32>(0, (num));
		z = 100 - z;
		Geometry::CustomObject* custom = createCubeMesh("Cube", "BaseGreen", activeRenderEngine->GetDeviceBufferManager(), activeMaterialManager);
		Scene::SceneNode* node = activeSceneManager->GetRootSceneNode()->CreateChildSceneNode();
		node->AttachObject(custom);
		node->SetTranslation(x, y,  z);
	}

}


